import ctypes
import time
import sys
from ctypes import *
from CANMessageTransmitter import CANMessageTransmitter

# 跨平台库加载：根据操作系统自动选择正确的库文件
if sys.platform.startswith('win'):
    # Windows系统：使用windll加载DLL文件
    canDLL = ctypes.windll.LoadLibrary("./ControlCANFD.dll")
    print("✅ Windows系统：已加载ControlCANFD.dll")
elif sys.platform.startswith('linux'):
    # Linux系统：使用cdll加载SO文件
    canDLL = ctypes.cdll.LoadLibrary("./libcontrolcanfd.so")
    print("✅ Linux系统：已加载libcontrolcanfd.so")
else:
    # 其他操作系统：尝试加载默认库文件
    try:
        canDLL = ctypes.cdll.LoadLibrary("./libcontrolcanfd.so")
        print("✅ 其他系统：已加载libcontrolcanfd.so")
    except Exception as e:
        try:
            canDLL = ctypes.windll.LoadLibrary("./ControlCANFD.dll")
            print("✅ 其他系统：已加载ControlCANFD.dll")
        except Exception as e2:
            raise ImportError(f"无法加载CAN库文件：Windows错误：{e2}，Linux错误：{e}")

# -------------------------- 常量定义（参考手册3.1、6.2.1节及例程） --------------------------
# 设备类型（例程中USBCANFD设备类型为41，与手册6.2.1节示例一致）
VCI_USBCAN2 = 41  
# 状态码（例程中STATUS_OK=1，与库函数返回值定义匹配）
STATUS_OK = 1  
STATUS_ERR = 0
# 无效句柄（参考手册3.1节）
INVALID_DEVICE_HANDLE = 0
INVALID_CHANNEL_HANDLE = 0
# 帧类型（手册2.2节）
TYPE_CAN = 0       # 普通CAN
TYPE_CANFD = 1     # CANFD
# 滤波模式（手册3.22节）
FILTER_MODE_STD = 0  # 标准帧
FILTER_MODE_EXT = 1  # 扩展帧

# -------------------------- 数据结构定义（严格遵循手册2.2-2.8节及例程） --------------------------
# CAN通道初始化配置（手册2.2节 ZCAN_CHANNEL_INIT_CONFIG）
class _ZCAN_CHANNEL_CAN_INIT_CONFIG(ctypes.Structure):
    _fields_ = [("acc_code", ctypes.c_uint),    # 验收码
                ("acc_mask", ctypes.c_uint),    # 屏蔽码
                ("reserved", ctypes.c_uint),    # 保留
                ("filter", ctypes.c_ubyte),     # 滤波方式（0=双滤波，1=单滤波）
                ("timing0", ctypes.c_ubyte),    # 忽略
                ("timing1", ctypes.c_ubyte),    # 忽略
                ("mode", ctypes.c_ubyte)]       # 工作模式（0=正常，1=只听）

class _ZCAN_CHANNEL_CANFD_INIT_CONFIG(ctypes.Structure):
    _fields_ = [("acc_code", ctypes.c_uint),     # 验收码
                ("acc_mask", ctypes.c_uint),     # 屏蔽码
                ("abit_timing", ctypes.c_uint),  # 忽略
                ("dbit_timing", ctypes.c_uint),  # 忽略
                ("brp", ctypes.c_uint),          # 波特率预分频（设0）
                ("filter", ctypes.c_ubyte),      # 滤波方式
                ("mode", ctypes.c_ubyte),        # 工作模式
                ("pad", ctypes.c_ushort),        # 数据对齐
                ("reserved", ctypes.c_uint)]     # 保留

# 联合结构体（手册2.2节 union）
class _ZCAN_CHANNEL_INIT_CONFIG(ctypes.Union):
    _fields_ = [("can", _ZCAN_CHANNEL_CAN_INIT_CONFIG),
                ("canfd", _ZCAN_CHANNEL_CANFD_INIT_CONFIG)]

# 通道初始化总配置（手册2.2节）
class ZCAN_CHANNEL_INIT_CONFIG(ctypes.Structure):
    _fields_ = [("can_type", ctypes.c_uint),          # 设备类型（TYPE_CAN/TYPE_CANFD）
                ("config", _ZCAN_CHANNEL_INIT_CONFIG)] # 联合配置

# CAN帧结构（手册2.3节 can_frame）
class ZCAN_CAN_FRAME(ctypes.Structure):
    _fields_ = [("can_id", ctypes.c_uint, 29),  # 帧ID（低29位）
                ("err", ctypes.c_uint, 1),     # 错误帧标志（0=正常）
                ("rtr", ctypes.c_uint, 1),     # 远程帧标志（0=数据帧）
                ("eff", ctypes.c_uint, 1),     # 扩展帧标志（0=标准帧，1=扩展帧）
                ("can_dlc", ctypes.c_ubyte),   # 数据长度（0-8）
                ("__pad", ctypes.c_ubyte),     # 对齐
                ("__res0", ctypes.c_ubyte),    # 保留
                ("__res1", ctypes.c_ubyte),    # 保留
                ("data", ctypes.c_ubyte * 8)]  # 数据域

# CANFD帧结构（手册2.4节 canfd_frame）
class ZCAN_CANFD_FRAME(ctypes.Structure):
    _fields_ = [("can_id", ctypes.c_uint, 29),  # 帧ID（低29位）
                ("err", ctypes.c_uint, 1),     # 错误帧标志（0=正常）
                ("rtr", ctypes.c_uint, 1),     # 远程帧标志（0=数据帧）
                ("eff", ctypes.c_uint, 1),     # 扩展帧标志（0=标准帧，1=扩展帧）
                ("brs", ctypes.c_uint, 1),     # 比特率切换（0=不切换，1=切换）
                ("esi", ctypes.c_uint, 1),     # 错误状态指示（0=主动错误，1=被动错误）
                ("canfd_dlc", ctypes.c_ubyte), # 数据长度（0-64）
                ("__pad", ctypes.c_ubyte),     # 对齐
                ("__res0", ctypes.c_ubyte),    # 保留
                ("__res1", ctypes.c_ubyte),    # 保留
                ("data", ctypes.c_ubyte * 64)] # 数据域（最大64字节）

# 发送数据结构（手册2.5节 ZCAN_Transmit_Data）
class ZCAN_Transmit_Data(ctypes.Structure):
    _fields_ = [("frame", ZCAN_CAN_FRAME),          # CAN帧
                ("transmit_type", ctypes.c_uint)]    # 发送方式（0=正常发送）

# CANFD发送数据结构（手册2.6节 ZCAN_TransmitFD_Data）
class ZCAN_TransmitFD_Data(ctypes.Structure):
    _fields_ = [("frame", ZCAN_CANFD_FRAME),        # CANFD帧
                ("transmit_type", ctypes.c_uint)]    # 发送方式（0=正常发送）

# 接收数据结构（手册2.7节 ZCAN_Receive_Data）
class ZCAN_Receive_Data(ctypes.Structure):
    _fields_ = [("frame", ZCAN_CAN_FRAME),          # CAN帧
                ("timestamp", ctypes.c_ulonglong)]   # 时间戳（微秒）

# CANFD接收数据结构（手册2.8节 ZCAN_ReceiveFD_Data）
class ZCAN_ReceiveFD_Data(ctypes.Structure):
    _fields_ = [("frame", ZCAN_CANFD_FRAME),        # CANFD帧
                ("timestamp", ctypes.c_ulonglong)]   # 时间戳（微秒）

# -------------------------- 函数参数类型声明（参考手册3.1-3.25节及例程） --------------------------
# 打开设备（手册3.1节 ZCAN_OpenDevice）
canDLL.ZCAN_OpenDevice.restype = ctypes.c_void_p
canDLL.ZCAN_OpenDevice.argtypes = (ctypes.c_uint, ctypes.c_uint, ctypes.c_uint)

# 设置CANFD仲裁域波特率（手册3.16节 ZCAN_SetAbitBaud）
canDLL.ZCAN_SetAbitBaud.restype = ctypes.c_uint
canDLL.ZCAN_SetAbitBaud.argtypes = (ctypes.c_void_p, ctypes.c_ulong, ctypes.c_ulong)

# 设置CANFD数据域波特率（手册3.17节 ZCAN_SetDbitBaud）
canDLL.ZCAN_SetDbitBaud.restype = ctypes.c_uint
canDLL.ZCAN_SetDbitBaud.argtypes = (ctypes.c_void_p, ctypes.c_ulong, ctypes.c_ulong)

# 设置CANFD标准（手册3.19节 ZCAN_SetCANFDStandard）
canDLL.ZCAN_SetCANFDStandard.restype = ctypes.c_uint
canDLL.ZCAN_SetCANFDStandard.argtypes = (ctypes.c_void_p, ctypes.c_ulong, ctypes.c_ulong)

# 初始化CAN通道（手册3.5节 ZCAN_InitCAN）
canDLL.ZCAN_InitCAN.restype = ctypes.c_void_p
canDLL.ZCAN_InitCAN.argtypes = (ctypes.c_void_p, ctypes.c_ulong, ctypes.c_void_p)

# 启动CAN通道（手册3.6节 ZCAN_StartCAN）
canDLL.ZCAN_StartCAN.restype = ctypes.c_uint
canDLL.ZCAN_StartCAN.argtypes = (ctypes.c_void_p,)

# 发送CAN报文（手册3.9节 ZCAN_Transmit）
canDLL.ZCAN_Transmit.restype = ctypes.c_uint
canDLL.ZCAN_Transmit.argtypes = (ctypes.c_void_p, ctypes.c_void_p, ctypes.c_ulong)

# 发送CANFD报文（手册3.10节 ZCAN_TransmitFD）
canDLL.ZCAN_TransmitFD.restype = ctypes.c_uint
canDLL.ZCAN_TransmitFD.argtypes = (ctypes.c_void_p, ctypes.c_void_p, ctypes.c_ulong)

# 获取接收缓冲区帧数（手册3.11节 ZCAN_GetReceiveNum）
canDLL.ZCAN_GetReceiveNum.restype = ctypes.c_uint
canDLL.ZCAN_GetReceiveNum.argtypes = (ctypes.c_void_p, ctypes.c_ulong)

# 接收CAN报文（手册3.12节 ZCAN_Receive）
canDLL.ZCAN_Receive.restype = ctypes.c_uint
canDLL.ZCAN_Receive.argtypes = (ctypes.c_void_p, ctypes.c_void_p, ctypes.c_ulong, ctypes.c_long)

# 接收CANFD报文（手册3.13节 ZCAN_ReceiveFD）
canDLL.ZCAN_ReceiveFD.restype = ctypes.c_uint
canDLL.ZCAN_ReceiveFD.argtypes = (ctypes.c_void_p, ctypes.c_void_p, ctypes.c_ulong, ctypes.c_long)

# 清除滤波配置（手册3.21节 ZCAN_ClearFilter）
canDLL.ZCAN_ClearFilter.restype = ctypes.c_uint
canDLL.ZCAN_ClearFilter.argtypes = (ctypes.c_void_p,)

# 设置滤波模式（手册3.22节 ZCAN_SetFilterMode）
canDLL.ZCAN_SetFilterMode.restype = ctypes.c_uint
canDLL.ZCAN_SetFilterMode.argtypes = (ctypes.c_void_p, ctypes.c_ulong)

# 设置滤波起始ID（手册3.23节 ZCAN_SetFilterStartID）
canDLL.ZCAN_SetFilterStartID.restype = ctypes.c_uint
canDLL.ZCAN_SetFilterStartID.argtypes = (ctypes.c_void_p, ctypes.c_ulong)

# 设置滤波结束ID（手册3.24节 ZCAN_SetFilterEndID）
canDLL.ZCAN_SetFilterEndID.restype = ctypes.c_uint
canDLL.ZCAN_SetFilterEndID.argtypes = (ctypes.c_void_p, ctypes.c_ulong)

# 生效滤波配置（手册3.25节 ZCAN_AckFilter）
canDLL.ZCAN_AckFilter.restype = ctypes.c_uint
canDLL.ZCAN_AckFilter.argtypes = (ctypes.c_void_p,)

# 复位CAN通道（手册3.7节 ZCAN_ResetCAN）
canDLL.ZCAN_ResetCAN.restype = ctypes.c_uint
canDLL.ZCAN_ResetCAN.argtypes = (ctypes.c_void_p,)

# 关闭设备（手册3.2节 ZCAN_CloseDevice）
canDLL.ZCAN_CloseDevice.restype = ctypes.c_uint
canDLL.ZCAN_CloseDevice.argtypes = (ctypes.c_void_p,)

# -------------------------- 传输基类 --------------------------
class ZCANTransmitter(CANMessageTransmitter):
    """封装底层CAN/CANFD发送、接收与设备生命周期管理"""

    def __init__(self, channel_handle):
        self.channel_handle = channel_handle

    def _send_can_data(self, send_id, data_list, is_ext_frame=False, canfd_mode=False, brs=0, esi=0):
        """发送CAN/CANFD数据（抽取自原CANMessageSequence）"""
        if canfd_mode:
            # CANFD模式发送
            transmit_data = ZCAN_TransmitFD_Data()
            transmit_data.frame.can_id = send_id
            transmit_data.frame.eff = 1 if is_ext_frame else 0
            transmit_data.frame.rtr = 0
            transmit_data.frame.err = 0
            transmit_data.frame.brs = brs
            transmit_data.frame.esi = esi
            transmit_data.frame.canfd_dlc = len(data_list) if len(data_list) <= 64 else 64
            for i in range(transmit_data.frame.canfd_dlc):
                transmit_data.frame.data[i] = data_list[i]
            transmit_data.transmit_type = 0
            ret = canDLL.ZCAN_TransmitFD(self.channel_handle, ctypes.byref(transmit_data), 1)
            if ret == 1:
                frame_type = "扩展帧" if is_ext_frame else "标准帧"
                brs_desc = "比特率切换" if brs else "无比特率切换"
                print(f"\n✅ CANFD Send to 0x{send_id:x} ({frame_type}) success!")
                print(f"   DLC: {transmit_data.frame.canfd_dlc}, {brs_desc}, Data: {[hex(d) for d in data_list]}")
                return True
            else:
                frame_type = "扩展帧" if is_ext_frame else "标准帧"
                print(f"\n❌ CANFD Send to 0x{send_id:x} ({frame_type}) failed!（返回值：{ret}）")
                return False
        else:
            # CAN模式发送
            transmit_data = ZCAN_Transmit_Data()
            transmit_data.frame.can_id = send_id
            transmit_data.frame.eff = 1 if is_ext_frame else 0
            transmit_data.frame.rtr = 0
            transmit_data.frame.err = 0
            transmit_data.frame.can_dlc = len(data_list) if len(data_list) <= 8 else 8
            for i in range(transmit_data.frame.can_dlc):
                transmit_data.frame.data[i] = data_list[i]
            transmit_data.transmit_type = 0
            ret = canDLL.ZCAN_Transmit(self.channel_handle, ctypes.byref(transmit_data), 1)
            if ret == 1:
                frame_type = "扩展帧" if is_ext_frame else "标准帧"
                print(f"\n✅ CAN Send to 0x{send_id:x} ({frame_type}) success!")
                print(f"   DLC: {transmit_data.frame.can_dlc}, Data: {[hex(d) for d in data_list]}")
                return True
            else:
                frame_type = "扩展帧" if is_ext_frame else "标准帧"
                print(f"\n❌ CAN Send to 0x{send_id:x} ({frame_type}) failed!（返回值：{ret}）")
                return False

    def _clear_receive_buffer(self):
        """
        通过循环读取并丢弃所有待处理的CAN消息来清空接收缓冲区。
        这是一个比ZCAN_ResetCAN更温和的方法，可以避免重置整个通道的状态。
        （抽取自原CANMessageSequence）
        """
        for frame_type in [TYPE_CAN, TYPE_CANFD]:
            pending_messages = canDLL.ZCAN_GetReceiveNum(self.channel_handle, frame_type)
            if pending_messages > 0:
                print(f"⚠️  检测到缓冲区有 {pending_messages} 条陈旧消息(类型={frame_type})，正在清空...")
                if frame_type == TYPE_CANFD:
                    rcv_buf = (ZCAN_ReceiveFD_Data * pending_messages)()
                    canDLL.ZCAN_ReceiveFD(self.channel_handle, ctypes.byref(rcv_buf), pending_messages, 0)
                else:
                    rcv_buf = (ZCAN_Receive_Data * pending_messages)()
                    canDLL.ZCAN_Receive(self.channel_handle, ctypes.byref(rcv_buf), pending_messages, 0)
                print(f"✅  缓冲区已清空。")

    def _receive_can_data(self, target_id=None, timeout=5, is_ext_frame=None, canfd_mode=False):
        """接收CAN/CANFD数据，并在开始接收前清空硬件缓冲区（抽取自原CANMessageSequence）"""
        self._clear_receive_buffer()
        start_time = time.time()
        if canfd_mode:
            rcv_buf = (ZCAN_ReceiveFD_Data * 2500)()
        else:
            rcv_buf = (ZCAN_Receive_Data * 2500)()
        while time.time() - start_time < timeout:
            frame_type = TYPE_CANFD if canfd_mode else TYPE_CAN
            count = canDLL.ZCAN_GetReceiveNum(self.channel_handle, frame_type)
            if count > 0:
                if canfd_mode:
                    read_len = canDLL.ZCAN_ReceiveFD(self.channel_handle, ctypes.byref(rcv_buf), count, -1)
                else:
                    read_len = canDLL.ZCAN_Receive(self.channel_handle, ctypes.byref(rcv_buf), count, -1)
                if read_len <= 0:
                    time.sleep(0.1)
                    continue
                print(f"\n✅ Received {read_len} frame(s):")
                for i in range(read_len):
                    if canfd_mode:
                        recv_id = rcv_buf[i].frame.can_id
                        recv_eff = rcv_buf[i].frame.eff
                        recv_rtr = rcv_buf[i].frame.rtr
                        recv_err = rcv_buf[i].frame.err
                        recv_brs = rcv_buf[i].frame.brs
                        recv_esi = rcv_buf[i].frame.esi
                        recv_dlc = rcv_buf[i].frame.canfd_dlc
                    else:
                        recv_id = rcv_buf[i].frame.can_id
                        recv_eff = rcv_buf[i].frame.eff
                        recv_rtr = rcv_buf[i].frame.rtr
                        recv_err = rcv_buf[i].frame.err
                        recv_dlc = rcv_buf[i].frame.can_dlc
                    if recv_err == 1 or recv_rtr == 1:
                        continue
                    id_match = target_id is None or recv_id == target_id
                    type_match = is_ext_frame is None or recv_eff == (1 if is_ext_frame else 0)
                    if id_match and type_match:
                        if canfd_mode:
                            data = [rcv_buf[i].frame.data[j] for j in range(recv_dlc)]
                            frame_type_desc = "扩展帧" if recv_eff == 1 else "标准帧"
                            brs_desc = "比特率切换" if recv_brs else "无比特率切换"
                            esi_desc = "被动错误" if recv_esi else "主动错误"
                            print(f"   ID: 0x{recv_id:x} ({frame_type_desc}), DLC: {recv_dlc}, {brs_desc}, {esi_desc}, Data: {[hex(d) for d in data]}")
                        else:
                            data = [rcv_buf[i].frame.data[j] for j in range(recv_dlc)]
                            frame_type_desc = "扩展帧" if recv_eff == 1 else "标准帧"
                            print(f"   ID: 0x{recv_id:x} ({frame_type_desc}), DLC: {recv_dlc}, Data: {[hex(d) for d in data]}")
                        return True, data
                    else:
                        frame_type_desc = "扩展帧" if recv_eff == 1 else "标准帧"
                        if canfd_mode:
                            brs_desc = "比特率切换" if recv_brs else "无比特率切换"
                            print(f"   [跳过] ID: 0x{recv_id:x} ({frame_type_desc}), DLC: {recv_dlc}, {brs_desc}, 不匹配目标ID: 0x{target_id:x} 或帧类型: {is_ext_frame}")
                        else:
                            print(f"   [跳过] ID: 0x{recv_id:x} ({frame_type_desc}), DLC: {recv_dlc}, 不匹配目标ID: 0x{target_id:x} 或帧类型: {is_ext_frame}")
            time.sleep(0.1)
        target_desc = f"0x{target_id:x}" if target_id is not None else "所有帧"
        frame_type_desc = "扩展帧" if is_ext_frame else "标准帧" if is_ext_frame is not None else "所有类型帧"
        mode_desc = "CANFD" if canfd_mode else "CAN"
        print(f"\n❌ {mode_desc} Receive {target_desc} ({frame_type_desc}) timeout!（超时{timeout}秒）")
        return False, []

    @staticmethod
    def init_can_device(baud_rate=500000, dbit_baud_rate=2000000, channels=[0], can_type=TYPE_CANFD, canfd_standard=0, channel_count=None):
        """
        初始化CAN设备，支持自定义波特率、CAN/CANFD模式选择和指定通道初始化
        （抽取自原模块方法）
        """
        # 处理向后兼容的channel_count参数
        if channel_count is not None:
            if channel_count == 1:
                channels = [0]
            elif channel_count == 2:
                channels = [0, 1]
            else:
                print("❌ 无效的通道数量，仅支持1或2个通道")
                return None, None, None
        if not channels or not all(ch in [0, 1] for ch in channels):
            print("❌ 无效的通道列表，仅支持[0]或[1]或[0,1]")
            return None, None, None
        if baud_rate < 33330 or baud_rate > 1000000:
            print(f"❌ 仲裁域波特率{baud_rate}超出范围(33.33Kbps-1Mbps)")
            return None, None, None
        if can_type == TYPE_CANFD:
            if dbit_baud_rate < 100000 or dbit_baud_rate > 5000000:
                print(f"❌ 数据域波特率{dbit_baud_rate}超出范围(100Kbps-5Mbps)")
                return None, None, None
        if can_type not in [TYPE_CAN, TYPE_CANFD]:
            print(f"❌ can_type参数值{can_type}无效，应为{TYPE_CAN}或{TYPE_CANFD}")
            return None, None, None
        if canfd_standard not in [0, 1]:
            print(f"❌ canfd_standard参数值{canfd_standard}无效，应为0(ISO)或1(BOSCH)")
            return None, None, None
        can_mode = "CANFD" if can_type == TYPE_CANFD else "CAN"
        canfd_standard_name = "ISO" if canfd_standard == 0 else "BOSCH"
        print(f"🔧 初始化{can_mode}设备，仲裁域波特率: {baud_rate}bps")
        if can_type == TYPE_CANFD:
            print(f"🔧 数据域波特率: {dbit_baud_rate}bps")
            print(f"🔧 CANFD标准: {canfd_standard_name}")
        print(f"🔧 通道: {channels}")
        m_dev = canDLL.ZCAN_OpenDevice(VCI_USBCAN2, 0, 0)
        if m_dev == INVALID_DEVICE_HANDLE:
            print("❌ Open Device failed!（检查DLL路径/设备类型/硬件连接）")
            return None, None, None
        print(f"✅ Open Device OK, device handle:0x{ctypes.c_uint64(m_dev).value:x}")
        dev_ch0 = None
        dev_ch1 = None
        # 通道0初始化
        if 0 in channels:
            ret = canDLL.ZCAN_SetAbitBaud(m_dev, 0, baud_rate)
            if ret != STATUS_OK:
                print(f"❌ Set CAN0 abit:{baud_rate}bps failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            print(f"✅ Set CAN0 abit:{baud_rate}bps OK!")
            if can_type == TYPE_CANFD:
                ret = canDLL.ZCAN_SetDbitBaud(m_dev, 0, dbit_baud_rate)
                if ret != STATUS_OK:
                    print(f"❌ Set CAN0 dbit:{dbit_baud_rate}bps failed!")
                    canDLL.ZCAN_CloseDevice(m_dev)
                    return None, None, None
                print(f"✅ Set CAN0 dbit:{dbit_baud_rate}bps OK!")
            if can_type == TYPE_CANFD:
                ret = canDLL.ZCAN_SetCANFDStandard(m_dev, 0, canfd_standard)
                if ret != STATUS_OK:
                    standard_name = "ISO" if canfd_standard == 0 else "BOSCH"
                    print(f"❌ Set CAN0 {standard_name} mode failed!")
                    canDLL.ZCAN_CloseDevice(m_dev)
                    return None, None, None
                standard_name = "ISO" if canfd_standard == 0 else "BOSCH"
                print(f"✅ Set CAN0 {standard_name} mode OK!")
            init_config = ZCAN_CHANNEL_INIT_CONFIG()
            init_config.can_type = can_type
            if can_type == TYPE_CANFD:
                init_config.config.canfd.acc_code = 0x00000000
                init_config.config.canfd.acc_mask = 0xFFFFFFFF
                init_config.config.canfd.filter = 0
                init_config.config.canfd.mode = 0
                init_config.config.canfd.brp = 0
                init_config.config.canfd.reserved = 0
            else:
                init_config.config.can.acc_code = 0x00000000
                init_config.config.can.acc_mask = 0xFFFFFFFF
                init_config.config.can.filter = 0
                init_config.config.can.mode = 0
                init_config.config.can.brp = 0
                init_config.config.can.reserved = 0
            dev_ch0 = canDLL.ZCAN_InitCAN(m_dev, 0, ctypes.byref(init_config))
            if dev_ch0 == INVALID_CHANNEL_HANDLE:
                print("❌ Init CAN0 failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            print("✅ Init CAN0 OK!")
            ret = canDLL.ZCAN_ClearFilter(dev_ch0)
            if ret != STATUS_OK:
                print("❌ Clear CAN0 filter failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            ret = canDLL.ZCAN_SetFilterMode(dev_ch0, FILTER_MODE_STD)
            if ret != STATUS_OK:
                print("❌ Set CAN0 standard frame filter mode failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            ret = canDLL.ZCAN_SetFilterStartID(dev_ch0, 0x000)
            if ret != STATUS_OK:
                print("❌ Set CAN0 standard frame filter start ID failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            ret = canDLL.ZCAN_SetFilterEndID(dev_ch0, 0x7FF)
            if ret != STATUS_OK:
                print("❌ Set CAN0 standard frame filter end ID failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            ret = canDLL.ZCAN_SetFilterMode(dev_ch0, FILTER_MODE_EXT)
            if ret != STATUS_OK:
                print("❌ Set CAN0 extended frame filter mode failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            ret = canDLL.ZCAN_SetFilterStartID(dev_ch0, 0x00000000)
            if ret != STATUS_OK:
                print("❌ Set CAN0 extended frame filter start ID failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            ret = canDLL.ZCAN_SetFilterEndID(dev_ch0, 0x1FFFFFFF)
            if ret != STATUS_OK:
                print("❌ Set CAN0 extended frame filter end ID failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            ret = canDLL.ZCAN_AckFilter(dev_ch0)
            if ret != STATUS_OK:
                print("❌ Ack CAN0 filter failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            print("✅ Configure CAN0 filter OK!（接收所有标准帧ID 0x000-0x7FF 和扩展帧ID 0x00000000-0x1FFFFFFF）")
            ret = canDLL.ZCAN_StartCAN(dev_ch0)
            if ret != STATUS_OK:
                print("❌ Start CAN0 failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            print("✅ Start CAN0 OK!")
        else:
            print("🔧 跳过通道0初始化")
        # 通道1初始化
        if 1 in channels:
            ret = canDLL.ZCAN_SetAbitBaud(m_dev, 1, baud_rate)
            if ret != STATUS_OK:
                print(f"❌ Set CAN1 abit:{baud_rate}bps failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            print(f"✅ Set CAN1 abit:{baud_rate}bps OK!")
            if can_type == TYPE_CANFD:
                ret = canDLL.ZCAN_SetDbitBaud(m_dev, 1, dbit_baud_rate)
                if ret != STATUS_OK:
                    print(f"❌ Set CAN1 dbit:{dbit_baud_rate}bps failed!")
                    canDLL.ZCAN_CloseDevice(m_dev)
                    return None, None, None
                print(f"✅ Set CAN1 dbit:{dbit_baud_rate}bps OK!")
            if can_type == TYPE_CANFD:
                ret = canDLL.ZCAN_SetCANFDStandard(m_dev, 1, canfd_standard)
                if ret != STATUS_OK:
                    standard_name = "ISO" if canfd_standard == 0 else "BOSCH"
                    print(f"❌ Set CAN1 {standard_name} mode failed!")
                    canDLL.ZCAN_CloseDevice(m_dev)
                    return None, None, None
                standard_name = "ISO" if canfd_standard == 0 else "BOSCH"
                print(f"✅ Set CAN1 {standard_name} mode OK!")
            init_config_ch1 = ZCAN_CHANNEL_INIT_CONFIG()
            init_config_ch1.can_type = can_type
            if can_type == TYPE_CANFD:
                init_config_ch1.config.canfd.acc_code = 0x00000000
                init_config_ch1.config.canfd.acc_mask = 0xFFFFFFFF
                init_config_ch1.config.canfd.filter = 0
                init_config_ch1.config.canfd.mode = 0
                init_config_ch1.config.canfd.brp = 0
                init_config_ch1.config.canfd.reserved = 0
            else:
                init_config_ch1.config.can.acc_code = 0x00000000
                init_config_ch1.config.can.acc_mask = 0xFFFFFFFF
                init_config_ch1.config.can.filter = 0
                init_config_ch1.config.can.mode = 0
                init_config_ch1.config.can.brp = 0
                init_config_ch1.config.can.reserved = 0
            dev_ch1 = canDLL.ZCAN_InitCAN(m_dev, 1, ctypes.byref(init_config_ch1))
            if dev_ch1 == INVALID_CHANNEL_HANDLE:
                print("❌ Init CAN1 failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            print("✅ Init CAN1 OK!")
            ret = canDLL.ZCAN_ClearFilter(dev_ch1)
            if ret != STATUS_OK:
                print("❌ Clear CAN1 filter failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            ret = canDLL.ZCAN_SetFilterMode(dev_ch1, FILTER_MODE_STD)
            if ret != STATUS_OK:
                print("❌ Set CAN1 standard frame filter mode failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            ret = canDLL.ZCAN_SetFilterStartID(dev_ch1, 0x000)
            if ret != STATUS_OK:
                print("❌ Set CAN1 standard frame filter start ID failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            ret = canDLL.ZCAN_SetFilterEndID(dev_ch1, 0x7FF)
            if ret != STATUS_OK:
                print("❌ Set CAN1 standard frame filter end ID failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            ret = canDLL.ZCAN_SetFilterMode(dev_ch1, FILTER_MODE_EXT)
            if ret != STATUS_OK:
                print("❌ Set CAN1 extended frame filter mode failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            ret = canDLL.ZCAN_SetFilterStartID(dev_ch1, 0x00000000)
            if ret != STATUS_OK:
                print("❌ Set CAN1 extended frame filter start ID failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            ret = canDLL.ZCAN_SetFilterEndID(dev_ch1, 0x1FFFFFFF)
            if ret != STATUS_OK:
                print("❌ Set CAN1 extended frame filter end ID failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            ret = canDLL.ZCAN_AckFilter(dev_ch1)
            if ret != STATUS_OK:
                print("❌ Ack CAN1 filter failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            print("✅ Configure CAN1 filter OK!（接收所有标准帧ID 0x000-0x7FF 和扩展帧ID 0x00000000-0x1FFFFFFF）")
            ret = canDLL.ZCAN_StartCAN(dev_ch1)
            if ret != STATUS_OK:
                print("❌ Start CAN1 failed!")
                canDLL.ZCAN_CloseDevice(m_dev)
                return None, None, None
            print("✅ Start CAN1 OK!")
        else:
            print("🔧 跳过通道1初始化")
        initialized_channels = []
        if dev_ch0 is not None:
            initialized_channels.append("通道0")
        if dev_ch1 is not None:
            initialized_channels.append("通道1")
        if initialized_channels:
            print(f"🔧 CAN设备初始化完成，使用: {', '.join(initialized_channels)}")
        else:
            print("❌ 没有初始化任何通道")
            canDLL.ZCAN_CloseDevice(m_dev)
            return None, None, None
        return m_dev, dev_ch0, dev_ch1

    @staticmethod
    def close_can_device(m_dev, channel_handle0=None, channel_handle1=None):
        """关闭CAN设备（参考手册3.2/3.7节），支持单通道或双通道关闭（抽取自原模块方法）"""
        if channel_handle0:
            ret = canDLL.ZCAN_ResetCAN(channel_handle0)
            print(f"\n{'✅ Close Channel0 OK!' if ret == STATUS_OK else '❌ Close Channel0 failed!'}")
        if channel_handle1:
            ret = canDLL.ZCAN_ResetCAN(channel_handle1)
            print(f"{'✅ Close Channel1 OK!' if ret == STATUS_OK else '❌ Close Channel1 failed!'}")
        if m_dev:
            ret = canDLL.ZCAN_CloseDevice(m_dev)
            print(f"{'✅ Close Device OK!' if ret == STATUS_OK else '❌ Close Device failed!'}")

